/**
 * Copyright (C) 2010 Sergey Grigoriev <s.a.grigoriev@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.gmf.core

import org.apache.maven.project.MavenProject
import com.google.inject.Inject
import org.apache.maven.artifact.repository.ArtifactRepository
import org.apache.maven.artifact.resolver.ArtifactResolver
import com.google.inject.name.Named
import org.apache.maven.artifact.resolver.ArtifactResolutionResult
import org.apache.maven.artifact.Artifact
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest
import java.util.regex.Matcher

/**
 *  Resolves Maven artifacts
 */
class Resolver {
  
  @Inject
  MavenProject project

  @Inject
  ArtifactRepository localRepository

  @Inject
  @Named('remoteRepositories')
  List remoteRepositories

  @Inject
  ArtifactResolver resolver

  @Inject
  @Named('attachedArtifacts')
  private Set attachedArtifacts

  /**
   * Returns file pointing to the location of the specified dependency on local filesystem.
   * @param artifactString String representing an artifact in format
   *   groupId:artifactId,
   *   or groupId:artifactId:type,
   *   or groupId:artifactId:type:version
   * @return {@link File File}  pointing to the artifact. If type or version is missing, then the first
   * matching artifact is returned.
   */
  File resolve(String artifactString) {

    def map = FlexProjectUtils.parseArtifactString(artifactString)
    String groupId = map['groupId']
    String artifactId = map['artifactId']

    // First, find artifact in project dependencies by group and artifact name
    Set<Artifact> dependencyArtifacts = resolveDependencies(project) + attachedArtifacts

    Artifact artifact = dependencyArtifacts.find {
      boolean result = it.groupId == groupId && it.artifactId == artifactId
      String type = map['type']
      if (type) {
        result &= type.equalsIgnoreCase(it.type)
      }
      return result
    }
    if (artifact) {
      return artifact.file
    }

    throw new IllegalArgumentException("could not resolve dependency $artifactString")
  }


  private ArtifactResolutionResult resolveArtifact(Artifact artifact) {

    ArtifactResolutionRequest request = new ArtifactResolutionRequest()
    request.localRepository = localRepository
    request.remoteRepositories = remoteRepositories
    request.artifact = artifact
    request.resolveTransitively = true

    ArtifactResolutionResult resolution = resolver.resolve(request)
    return resolution
  }

  private Set<Artifact> resolveDependencies(MavenProject mavenProject) {

    Set<Artifact> result = new LinkedHashSet<Artifact>()

    mavenProject.dependencyArtifacts.each {Artifact a ->
      ArtifactResolutionResult resolution = resolveArtifact(a)
      result += resolution.artifacts
    }
    return result
  }
}
